package rx.genarator.comprehension;

import java.util.HashSet;
import java.util.Set;

public class Reference {
	
	
	public static final String ONE_PARENT_ZERO_OR_MORE_CHILDREN="0..*";
	public static final String ONE_PARENT_ZERO_OR_ONE_CHILDREN="0..1";
	public static final String ONE_PARENT_ONE_OR_MORE_CHILDREN="1..*";
	public static final String ONE_PARENT_ONE_CHILD="0..1";
	
	public static final String DEFAULT_NAME_PREFIX="reference-";
	
	private static int count;
	
	private static synchronized String getDefaultName(){
		return DEFAULT_NAME_PREFIX+(++count);
	}
	
	protected Table parentTable;
	
	protected Table childTable;
	
	protected String relation;
	
	protected String name;
	
	protected Key parentKey;
	
	protected Set<ReferenceJoin> joins =new HashSet<ReferenceJoin>();

	protected String id;
	

	public Reference(String id,String relation,String name,Table parentTable, Table childTable) {
		super();
		if(id==null||!validate(relation)||name==null||parentTable==null||childTable==null)throw new IllegalArgumentException("id:"+id+",relation:"+relation+",name:"+name+"parentTable:"+parentTable+",childTable:"+childTable);
		this.id=id;
		this.relation = relation;
		this.name = name;
		this.parentTable=parentTable;
		this.childTable=childTable;
		this.parentKey=parentTable.getPrimaryKey();
		ObjectsMap.put(id, this);
	}
	
	public Reference(String id,String relation,Table parentTable, Table childTable) {
		this(id,relation,getDefaultName(),parentTable,childTable);
	}

	public String getName() {
		return name;
	}


	public String getRelation() {
		return relation;
	}

	public static boolean validate(String value){
		return ONE_PARENT_ZERO_OR_MORE_CHILDREN.equals(value)||ONE_PARENT_ZERO_OR_ONE_CHILDREN.equals(value)||ONE_PARENT_ONE_OR_MORE_CHILDREN.equals(value)||ONE_PARENT_ONE_CHILD.equals(value);
	}

	public Table getChildTable() {
		return childTable;
	}


	public String getId() {
		return id;
	}

	public Set<ReferenceJoin> getJoins() {
		return new HashSet<ReferenceJoin>(joins);
	}

	public Key getParentKey() {
		return parentKey;
	}

	public Table getParentTable() {
		return parentTable;
	}
	
	public ReferenceJoin createReferenceJoin(String id,Column parentTableColumn,Column childTableColumn){
		if(!parentTable.columns.contains(parentTableColumn)||!childTable.columns.contains(childTableColumn))
			throw new IllegalArgumentException("id:"+id+",parentTableColumn:"+parentTableColumn+",childTableColumn:"+childTableColumn);
		
		childTableColumn.setStart(this);
		parentTableColumn.addEnd(this);
		ReferenceJoin join = new ReferenceJoin(this,id,parentTableColumn,childTableColumn);
		this.joins.add(join);
		return join;
	}
}
